package com.javasea.shiro.realm;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.ArrayList;
import java.util.List;

/**
 *@ClassName PermissionRealm
 *@Description 自定义Realms对象
 *@Author longxiaonan@163.com
 *@Date 2021/7/5 0005 22:30
 */
public class PermissionRealm extends AuthorizingRealm {

    @Override
    public void setName(String name) {
        super.setName("permissionRealm");
    }

    /** 认证的方法: 比较用户名和密码是否与数据库中的一致
     *   根据用户名和密码登陆，将用户数据保存
     * @param authenticationToken 登陆构造的UsernamePasswordToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 1.构造uptoken
        UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
        // 2.获取输入的用户名密码
        String username = upToken.getUsername();
        String password = new String(upToken.getPassword());
        // 3.根据用户名查询数据库
        // 4.比较密码和数据库中的密码是否一致（密码可能需要加密）
        if ("123456".equals(password)) {
            // 5.如果成功，向食肉存入安全数据
            // 1.安全数据，2.密码，3.当前realm域名称
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, getName());
            return info;
        } else {
            // 6.失败，抛出异常或返回null
            throw new RuntimeException("用户名或密码错误");
        }
    }

    /**
     * 授权：根据认证的数据获取到用户的权限信息
     *  获取到用户的授权数据（用户的权限数据
     * @param principalCollection 包含了所有已认证的安全数据
     * @return 授权数据
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 1.获取安全数据 username，用户id
        String primaryPrincipal = (String)principalCollection.getPrimaryPrincipal();
        // 2.根据id或者名称查询用户
        // 3.查询用户的角色和权限信息
        List<String> perms = new ArrayList<>();
        perms.add("user:save");
        perms.add("user:update");
        List<String> roles = new ArrayList<>();
        roles.add("role1");
        roles.add("role2");
        // 4.构造返回
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(perms);
        info.addRoles(roles);
        return info;
    }
}
